﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace GEAR_Structure
{
    [Serializable]
    public class Stratigraphy
    {
      
        
        public enum Formula_sound_insulation_index //tipo di formula per il calcolo del indice del potere fonoisolate Rw secondo UNI TR 11175
        { B1 = 1, B2, B3, B4, B5, Custom };
        
        public enum LiminarCoefficient {
            [EnumDescription("Parete verticale opaca verso esterno flusso termico orizontale")]
            Vertical_Wall_opaque_toward_the_outside_heat_flow_hor,
            [EnumDescription("Parete verticale opaca verso terreno flusso termico orizontale")]
            Vertical_Wall_opaque_toward_terrain_heat_flow_hor,
            [EnumDescription("Parete verticale opaca verso interno flusso termico orizontale")]
            Vertical_Wall_opaque_toward_internal_heat_flow_hor,
            [EnumDescription("Pavimento contro terra direzione flusso verso il basso")]
            Floor_against_earth_direction_downward_flow,
            [EnumDescription("Pavimento su spazio areato esterno direzione flusso verso il basso")]
            Floor_space_on_external_aerated_flow_directiondownwards,
            [EnumDescription("Pavimento su spazio areato interno direzione flusso verso il basso")]
            On_floor_space_inside_aerated_flow_direction_downwards,
            [EnumDescription("Solaio orizzontale verso esterno direzione flusso verso l'alto")]
            Horizontal_Floor_toward_outside_direction_upward_flow,
            [EnumDescription("Solaio orizzontale verso terreno (tetto giardino) direzione flusso verso l'alt")]
            Horizontal_Floor_toward_ground_roof_garden_direction_upward_flow,
            [EnumDescription("Solaio orizzontale verso ambiente interno direzione flusso verso l'alto")]
            Horizontal_Floor_toward_internal_environment_direction_upward_flow
        };

        public enum month //mesi dell'anno
        {Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre};

        private string name;//nome della stratigrafia
        private double indicePotereFonoisolante;//indice del potere fonoisolante Rw [dB]
        private Formula_sound_insulation_index formula_sound_index;//formula da usare per inpostare Rw
        private LiminarCoefficient surfaceresistance;//
        private month months_of_calculation;//mese di cui eseguire il calcolo 

        
        //private double sound_insulation_index;//indice del potere fonoisolante Rw [dB]
        private bool lock_sound_insulation_index;
        private double[] sound_insulation;//potere fonoisolante Rw [dB]
        private double permeance;//permeanza al vapor d'acqua [kg/(m²sPa)]
        private double rsi;//resistenza liminare interna
        private double rse;//resistenza liminare esterrna
        private BindingList<Materiale> layers;
        int type=2;//tipo di stratigrafia  o componente 1=vetro e telai 2=pareti verticali 3=solai orizzontali
        /*
        private double[][] profiloTemperature;

        public double[][] ProfiloTemperature
        {
            get { return UNI.Energy.UniEnIso13788.Calcoli.ProfiloTeper(this, p, ic);
                
                profiloTemperature; }
            //set { profiloTemperature = value; }
        }
*/
        public month Months_of_calculation
        {
            get { return months_of_calculation; }
            set { months_of_calculation = value; }
        }

        public int Type
        {
            get { return type; }
            set { type = value; }
        }

        public double Rse
        {
            get { return rse; }
            set { rse = value; }
        }

        public double Rsi
        {
            get { return rsi; }
            set { rsi = value; }
        }

        //costruttore
        public Stratigraphy(Stratigraphy s)
        {
            this.name = s.name;
            this.indicePotereFonoisolante = s.indicePotereFonoisolante;
            this.formula_sound_index = s.formula_sound_index;
            this.lock_sound_insulation_index = s.lock_sound_insulation_index;
            this.sound_insulation = s.sound_insulation;
            this.permeance = s.permeance;
            this.rsi = s.rsi;
            this.rse = s.rse;
            this.surfaceresistance = s.surfaceresistance;
            this.layers = new BindingList<Materiale>(layers);
        }

        public Stratigraphy()
        {
            this.name = "";
            this.indicePotereFonoisolante = 0;
            this.formula_sound_index = Formula_sound_insulation_index.B1;
            this.lock_sound_insulation_index = false;
            this.sound_insulation = null;
            this.permeance = 0;
            this.rsi = 0;
            this.rse = 0;
            this.surfaceresistance = LiminarCoefficient.Floor_against_earth_direction_downward_flow;
            this.layers = new BindingList<Materiale>();
        }

        public LiminarCoefficient SurfaceResistance
        {
            get { return surfaceresistance; }
            set 
            {
                if (value != surfaceresistance)
                {
                    
                    surfaceresistance = value;
                    switch (surfaceresistance)
                    {
                        case LiminarCoefficient.Vertical_Wall_opaque_toward_the_outside_heat_flow_hor:
                            rsi = 0.13;
                            rse = 0.04;
                            break;
                        case LiminarCoefficient.Vertical_Wall_opaque_toward_terrain_heat_flow_hor:
                            rsi = 0.13;
                            rse = 0;
                            break;
                        case LiminarCoefficient.Vertical_Wall_opaque_toward_internal_heat_flow_hor:
                            rsi = 0.13;
                            rse = 0.13;
                            break;
                        case LiminarCoefficient.Floor_against_earth_direction_downward_flow:
                            rsi = 0.17;
                            rse = 0;
                            break;
                        case LiminarCoefficient.Floor_space_on_external_aerated_flow_directiondownwards:
                            rsi = 0.17;
                            rse = 0.04;
                            break;
                        case LiminarCoefficient.On_floor_space_inside_aerated_flow_direction_downwards:
                            rsi = 0.17;
                            rse = 0.17;
                            break;
                        case LiminarCoefficient.Horizontal_Floor_toward_outside_direction_upward_flow:
                            rsi = 0.1;
                            rse = 0.04;
                            break;
                        case LiminarCoefficient.Horizontal_Floor_toward_ground_roof_garden_direction_upward_flow:
                            rsi = 0.1;
                            rse = 0;
                            break;
                        case LiminarCoefficient.Horizontal_Floor_toward_internal_environment_direction_upward_flow:
                            rsi = 0.1;
                            rse = 0.1;
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// Massa superficiale secondo D.Lgs 311/06 [kg/²]
        /// </summary>
        public double SurfaceMass
        {
            get
            {
                return UNI.Energy.DM26Giu2009.SurfaceMass(this);
                

            }

        }
        /// <summary>
        /// Conduttanza della stratigrafia C' [W/(m²K)]
        /// </summary>
        public double Conduttance
        {
            get
            {
                return 1/UNI.Energy.UniEnIso6946.Rtot(this);
            }
        }
        /// <summary>
        /// Massa frontale dell stratigrafia [kg/m²]
        /// </summary>
        public double FrontalMass
        {
            get
            {
                return UNI.Acoustic.UniTr11175.Frontal_Mass(this);       
            }
        }
        /// <summary>
        /// Resistenza termica della statigrafia [m²K/W]
        /// </summary>
        public double TermalResistace
        {
            get
            {
                return UNI.Energy.UniEnIso6946.Rtot(this);
            }

        }
        /// <summary>
        /// Trasmittanza termica della stratigrafia [W/(m²K)]
        /// </summary>
        public double Trasmitance
        {
            get
            {
                return 1 / UNI.Energy.UniEnIso6946.RtotEnvironment(this);
            }

        }
        /// <summary>
        /// Resistenza alla difusione del vapore acqueo nella stratigrafia [m²sPa/kg]
        /// </summary>
        public double VaporResistace
        {
            get
            {
                return UNI.Energy.UniEnIso13788.Zptot(this);
            }

        }
        /// <summary>
        /// Permeanza al vapor d'acqua nella stratigrafia [kg/(m²sPa)]
        /// </summary>
        public double Permeance
        {
            get
            {
                return 1 / this.VaporResistace;
            }

        }
        /// <summary>
        /// nome della stratigrafia
        /// </summary>
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        
        public Formula_sound_insulation_index Formula_sound_index
        {
            get { return formula_sound_index; }
            set { formula_sound_index = value; }
        }

        public double Sound_insulation_index
        {
            get { return UNI.Acoustic.UniTr11175.R1w.Rw(this); }
            //set 
            //{
            //    if (!lock_sound_insulation_index)
            //        sound_insulation_index = value; 
            //}
        }

        public bool Lock_sound_insulation_index
        {
            get { return lock_sound_insulation_index; }
            set { lock_sound_insulation_index = value; }
        }
        
        public BindingList<Materiale> Layers
        {
            get { return layers; }
            set { layers = value; }
        }

        public void add(Materiale _layer)
        {
            _layer.PropertyChanged += new PropertyChangedEventHandler(_layer_PropertyChanged);
            layers.Add(_layer);
        }

        void _layer_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
        }

        public void remove(Materiale _layer)
        {
            layers.Remove(_layer);
        }

        public void remove(int index)
        {
            layers.RemoveAt(index);
        }
        /// <summary>
        /// Scambia la posizione di due layers apartenenti alla stratigrafia
        /// </summary>
        /// <param name="index_1">layer 1</param>
        /// <param name="index_2">layer 2</param>
        public void changeOrder(int index_1, int index_2)
        {
            Materiale tmp = layers[index_1];
            layers[index_1] = layers[index_2];
            layers[index_2] = tmp;
        }
        //restituisce la stratigrafia
        public BindingList<Materiale> bindingSource()
        {
            BindingList<Materiale> ret = new BindingList<Materiale>();
            foreach (Materiale l in layers)
                ret.Add(l);
            return ret;
        }

        public double[][] profiloTemperature(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.ProfiloTeper(this, p, ic);
        }



        public double[][] profiloPressioneVapore(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.ProfiloPressVap(this, p, ic);
        }

        public double[][] profiloPressioneVaporeSat(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.ProfiloPressVapSat(this, p, ic);
        }

        public double[][] fRsiMaxB1(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.fRsiMaxB1(p, ic);
        }

        public double[][] fRsiMaxB2(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.fRsiMaxB2(p, ic);
        }

        public double[][] fRsiMaxB3(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.fRsiMaxB3(p, ic);
        }

        public double[][] fRsiMaxB4(ClimateData.Province p, ClimateData.InternalClimate ic)
        {
            return UNI.Energy.UniEnIso13788.Calcoli.fRsiMaxB4(p, ic);
        }
        
    }
}
